// 设计一个生成短链接的服务
// 如 https://www.taobao.com/markets/nanzhuang/2017new?spm=a21bo.2017.201867-main.2.5af911d9vvdi9f
// 转化为 https://s.com/abcdef  （6个字符）
// 要求写出你的设计思路（前端，后端，数据库等），并给出具体的encode和decode函数


/**
 * 设计思路
 *
 * 在数据存储长短链接一一对应的数据
 * encode 函数首先查询数据库，看是否已经生成，若没有则取出所有短链接生成一份不重复短链接，并插入数据库
 * decode 函数直接返回数据库原有值
 *
 * */

var mongoose = require('mongoose');
var connection = mongoose.createConnection('mongodb://localhost/db');
var UrlSchema = new mongoose.Schema({
    'long': String,
    'short': String
});
// 向数据库查询所有链接
UrlSchema.statics.findAllShort = function (short, cb) {
    return this.model('Url').find({}, cb);
};
// 向数据库查询长链接
UrlSchema.statics.findLong = function (long, cb) {
    return this.model('Url').findOne({
        'long': long,
    }, cb);
};
const URl = connection.model('Url', ParkingSchema);

// 长链接转短链接
const encode = function (uri) {
    // 查询数据库是否有长链接 并向下一步传递
    var findLong = function (url) {
        return new Promise(function (resolve, reject) {
            URL.findLong(url, function (err, url) {
                if (!url) {
                    // 未查询到长链接，执行下一步操作
                    resolve({
                        next: true,
                        url: ''
                    })
                } else {
                    // 已查询到长链接
                    resolve({
                        next: false,
                        url: url.short
                    })
                }
            })
        });
    };

    // 查询数据库是否有短链接
    var createShort = function (long) {
        var dir = ['a', 'b', 'c', 'd', 'e', 'f'];

        // 生成随机网址的函数
        function getShort(shortArr) {
            var newShort = [];
            for (let i = 0; i <= 6; i++) {
                newShort.push(dir[Math.random() * dir.length]);
            }
            if (shortArr.find(newShort)) {
                getShort(shortArr)
            } else {
                return newShort;
            }
        }

        // 根据上一步结果进行判断
        if (long.next) {
            return new Promise(function (resolve, reject) {
                URL.findAllShort(long.url, function (err, url) {
                    if (!url) {
                        // 查询数据库所有值 生成一个不重复的短链接 并插入数据库
                        const urlList = [...url.map(val => {
                            return val.short
                        })];
                        const shortUrl = getShort(urlList);
                        const newUrl = new URl({
                            long: long.url,
                            short: shortUrl
                        });
                        newUrl.save();
                        resolve(shortUrl);
                    } else {
                        // 如果数据库为空，则执行
                        const shortUrl = getShort([]);
                        const newUrl = new URl({
                            long: long.url,
                            short: getShort(shortUrl)
                        });
                        newUrl.save();
                        resolve(shortUrl);
                    }
                })
            });
        } else {
            // 数据库已有数据，直接返回短链接
            return long.url
        }
    };

    // 执行查询
    async function go(url) {
        let longRes = await findLong(url);
        return await createShort(longRes);
    }

    return go(uri);
};
// 短链接转长链接 直接查询数据库
const decode = function (uri) {
    return new Promise(function (resolve, reject) {
        URL.findLong(uri, function (err, url) {
            if (!url) {
                resolve('404');
            } else {
                resolve(url.short);
            }
        })
    });
};
